/* Copyright (c) 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.orkut.client.api.samples.greetings.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
import com.google.orkut.client.api.samples.greetings.client.DataModel;
import com.google.orkut.client.api.samples.greetings.client.GreetingsCallbackWrapper;
import com.google.orkut.client.api.samples.greetings.client.GreetingsMessages;
import com.google.orkut.client.api.samples.greetings.client.DataModel.DataModelUpdateCallback;
import com.google.orkut.client.api.samples.greetings.client.selector.Item;
import com.google.orkut.client.api.samples.greetings.client.selector.ItemSection;
import com.google.orkut.client.api.samples.greetings.client.services.CaptchaInfo;
import com.google.orkut.client.api.samples.greetings.client.services.PhotoInfo;
import com.google.orkut.client.api.samples.greetings.client.services.UserInfo;
import com.google.orkut.client.api.samples.greetings.client.services.UserServiceAsync;
import com.google.orkut.client.api.samples.greetings.client.ui.ScrapSentDialogBox.ScrapSendDialogBoxCallback;
import com.google.orkut.client.api.samples.greetings.shared.CommonConstants;

import java.util.ArrayList;

/**
 * A UI widget to send a message [photo+text]. Also handles a
 * captcha solve request.
 *
 * @author Shishir Birmiwal
 */
public class ScrapModule extends Composite
implements AsyncCallback<CaptchaInfo>, DataModelUpdateCallback {

  public static interface ScrapModuleCallback {
    public void addMoreRecipients();
  }

  private static ScrapModuleUiBinder uiBinder = GWT.create(ScrapModuleUiBinder.class);
  private PhotoInfo photo;

  @UiField
  ItemSection itemSection;

  @UiField
  Image selectedPhoto;

  @UiField
  TextArea message;

  @UiField
  Image captchaImage;

  @UiField
  TextBox captchaAnswer;

  @UiField
  HTMLPanel captchaSection;

  @UiField
  FlowPanel previewArea;

  @UiField
  TextArea previewText;

  @UiField
  Image previewImage;

  @UiField
  CheckBox useSmallerImage;

  @UiField
  CheckBox postUpdate;

  private String captchaToken = "";
  private final UserServiceAsync userService;
  private final String st;
  private final GreetingsMessages msgs;
  private final ScrapSentDialogBox successDialog;
  private final ArrayList<UserInfo> recipients = new ArrayList<UserInfo>();
  private final GreetingsCallbackWrapper cbWrapper;
  private Item addUserItem;

  interface ScrapModuleUiBinder extends UiBinder<Widget, ScrapModule> {
  }

  @Inject
  public ScrapModule(
      DataModel dataModel,
      Provider<Item> itemsProvider,
      GreetingsMessages msgs,
      GreetingsCallbackWrapper cbWrapper,
      @Named("postToken") String st,
      UserServiceAsync userService,
      ScrapSentDialogBox succesDialog) {
    this.msgs = msgs;
    this.cbWrapper = cbWrapper;
    this.st = st;
    this.userService = userService;
    this.successDialog = succesDialog;
    initWidget(uiBinder.createAndBindUi(this));
    captchaSection.setVisible(false);
    previewArea.setVisible(false);
    dataModel.registerCallback(this);
  }

  public void setSelectedPhoto(PhotoInfo photo) {
    this.photo = photo;
    selectedPhoto.setUrl(photo.imageUrl);
  }

  public void setTitle(String title) {
    itemSection.setTitle(title);
  }

  @UiHandler("scrapButton")
  void onClick(ClickEvent event) {
    ArrayList<String> selectedIds = new ArrayList<String>();
    for (UserInfo user : recipients) {
      selectedIds.add(user.id);
    }
    previewArea.setVisible(false);
    userService.scrapUser(st, selectedIds, photo,
        useSmallerImage.getValue(), postUpdate.getValue(),
        message.getText(), captchaToken, captchaAnswer.getText(), cbWrapper.wrap(this));
  }

  @Override
  public void onFailure(Throwable caught) {
    Window.alert(msgs.failedToSendMessage());
  }

  @Override
  public void onSuccess(CaptchaInfo captcha) {
    if (captcha == null || captcha.captchaUrl == null || captcha.captchaUrl.trim().length() == 0) {
      successDialog.center();
      successDialog.setAnimationEnabled(true);
      successDialog.show();
      clearCaptcha();
      return;
    } else {
      showCaptcha(captcha);
    }
  }

  @UiHandler("scrapPreview")
  public void onPreviewClick(ClickEvent event) {
    previewText.setEnabled(false);
    previewText.setReadOnly(true);
    String msg = message.getText();
    previewText.setText(msg);
    int lastIndex = 0;
    int count = 0;
    while (true) {
      int indexOf = msg.indexOf('\n', lastIndex);
      if (indexOf < 0) {
        break;
      }
      count++;
      lastIndex = indexOf + 1;
      if (lastIndex > msg.length()) {
        break;
      }
    }
    previewText.setSize("99%", count + 1 + "el");
    previewText.setSize("99%", (count + 3) * 11 + "px");
    previewImage.setUrl(getPhotoUrl());
    previewArea.setVisible(true);
  }

  private String getPhotoUrl() {
    return CommonConstants.getImageUrl(photo, useSmallerImage.getValue());
  }

  private void showCaptcha(CaptchaInfo captcha) {
    captchaAnswer.setText("");
    captchaToken = captcha.captchaToken;
    captchaImage.setUrl(captcha.captchaUrl);
    captchaSection.setVisible(true);
  }

  void clearCaptcha() {
    captchaAnswer.setText("");
    captchaToken = "";
    captchaSection.setVisible(false);
  }

  public void setOnScrapSuccessCallback(ScrapSendDialogBoxCallback cb) {
    successDialog.setCallback(cb);
  }

  @Override
  public void update(DataModel data, Type type) {
    if (!Type.SELECTED_RECIPIENTS.equals(type)) {
      return;
    }
    if (data.selectedRecipients.isEmpty()) {
      itemSection.collapse();
      return;
    }

    recipients.clear();
    recipients.addAll(data.selectedRecipients);
    itemSection.expand();
    this.setVisible(true);
  }
}
